package com.potato369.cryptEureka.service.impl;

import com.potato369.cryptEureka.common.utils.JwtTokenUtil;
import com.potato369.cryptEureka.domain.Admin;
import com.potato369.cryptEureka.domain.Permission;
import com.potato369.cryptEureka.repository.AdminRepository;
import com.potato369.cryptEureka.repository.PermissionRepository;
import com.potato369.cryptEureka.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class AdminServiceImpl implements AdminService {

    private PermissionRepository permissionRepository;

    private AdminRepository repository;

    private UserDetailsService userDetailsService;

    private JwtTokenUtil jwtTokenUtil;

    private PasswordEncoder passwordEncoder;

    @Autowired
    public void setRepository(AdminRepository repository) {
        this.repository = repository;
    }

    @Autowired
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Autowired
    public void setPermissionRepository(PermissionRepository permissionRepository) {
        this.permissionRepository = permissionRepository;
    }

    @Autowired
    public void setJwtTokenUtil(JwtTokenUtil jwtTokenUtil) {
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @Autowired
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    /**
     * 根据用户名获取后台管理员
     *
     * @param username
     */
    @Override
    public Admin getAdminByUsername(String username) {
        List<Admin> adminList = this.repository.findByUsername(username);
        if (!Objects.isNull(adminList) && !adminList.isEmpty() && adminList.size() > 0) {
            return adminList.get(0);
        }
        return null;
    }

    /**
     * 注册功能
     *
     * @param umsAdminParam
     */
    @Override
    public Admin register(Admin umsAdminParam) {
        Admin umsAdmin = new Admin();
        BeanUtils.copyProperties(umsAdminParam, umsAdmin);
        //查询是否有相同用户名的用户
        List<Admin> adminList = this.repository.findByUsername(umsAdminParam.getUsername());
        if (!Objects.isNull(adminList) && !adminList.isEmpty() && adminList.size() > 0) {
            return null;
        }
        umsAdmin.setCreateTime(new Date());
        umsAdmin.setStatus(1);
        //将密码进行加密操作
        String encodePassword = this.passwordEncoder.encode(umsAdminParam.getPassword());
        umsAdmin.setPassword(encodePassword);
        return this.repository.save(umsAdmin);
    }

    /**
     * 登录功能
     *
     * @param username 用户名
     * @param password 密码
     * @return 生成的JWT的token
     */
    @Override
    public String login(String username, String password) {
        String token = null;
        try {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            if (!this.passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
        } catch (Exception e) {
            log.error("登录出现错误", e);
        }
        return token;
    }

    /**
     * 获取用户所有权限（包括角色权限和+-权限）
     *
     * @param adminId
     */
    @Override
    public List<Permission> getPermissionList(Long adminId) {
        return this.permissionRepository.getPermissionList(adminId);
    }
}
